<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Gitignore Online Generator</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.2/font/bootstrap-icons.css">
    <script src="script/gitignore.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.1/dist/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.min.js"></script>

    <!-- Google tag (gtag.js) -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=G-G71EH5JJVS"></script>
    <script>
        window.dataLayer = window.dataLayer || [];
        function gtag() { dataLayer.push(arguments); }
        gtag('js', new Date());
        gtag('config', 'G-G71EH5JJVS');
    </script>

    <style>
        a {
            text-decoration: none;
        }

        .x-border {
            border: 1px solid #ced4da;
            border-radius: 0.25rem;
            padding: 1rem;
        }

        .x-select-container {
            height: 220px;
            overflow-y: scroll;
        }

        .x-select {
            display: inline-block;
            width: 250px;
        }
    </style>
    <script>
        const IGNORE_COMMENT = '# generated by: https://gitignore.itranswarp.com/\n';
        const GITHUB_URL = 'https://github.com/michaelliao/gitignore-online-generator/blob/main/';
        const CUSTOM_IGNORE = '# add your custom gitignore here:\n!.gitignore\n!.gitsubmodules';
        const COMMON_IGNORES = ['Archives', 'Backup', 'Emacs', 'Linux', 'NotepadPP', 'PuTTY', 'SublimeText', 'Vim', 'VisualStudioCode', 'Windows', 'macOS'];
        const PRESETS = [
            {
                name: 'None',
                selection: []
            },
            {
                name: 'C/C++',
                selection: ['C', 'C++', 'CMake'].concat(COMMON_IGNORES)
            },
            {
                name: 'Go',
                selection: ['Go', 'JetBrains'].concat(COMMON_IGNORES)
            },
            {
                name: 'Java',
                selection: ['Java', 'Eclipse', 'Gradle', 'JetBrains', 'Maven', 'NetBeans'].concat(COMMON_IGNORES)
            },
            {
                name: 'Node',
                selection: ['Node'].concat(COMMON_IGNORES)
            },
            {
                name: 'PHP',
                selection: ['CakePHP', 'FuelPHP', 'Yii'].concat(COMMON_IGNORES)
            },
            {
                name: 'Python',
                selection: ['Python', 'JetBrains', 'VirtualEnv'].concat(COMMON_IGNORES)
            }
        ];

        window.downloadVersion = 0;

        async function generate_gitignore(version, list, url_list, custom) {
            console.log(version, list);
            $modal = $('#modal-generate');
            $prompt = $modal.find('#div-prompt');
            $prompt.html('');
            $download = $modal.find('#btn-download');
            $download.attr('href', '#0');
            $download.addClass('disabled');
            let
                i,
                blob,
                s = IGNORE_COMMENT,
                modal = new bootstrap.Modal($modal.get(0), { backdrop: 'static', 'keyboard': false });
            modal.show();
            for (i = 0; i < list.length; i++) {
                if (window.downloadVersion !== version) {
                    return;
                }
                $prompt.append('<p>' + (i + 1) + '/' + list.length + ': get ' + list[i] + '.gitignore...</p>');
                try {
                    let resp = await $.ajax({
                        url: url_list[i],
                        type: 'GET',
                        processData: false
                    });
                    s = s + '\n#################### ' + list[i] + '.gitignore ####################\n\n' + resp;
                } catch (err) {
                    console.log(err);
                    return;
                }
            }
            if (window.downloadVersion !== version) {
                return;
            }
            $prompt.append('<p>Click Download button to download file, rename to <code>.gitignore</code> and move it to a git repository directory.</p>');
            if (custom.trim() !== '') {
                s = s + '\n#################### Custom.gitignore ####################\n\n' + custom + '\n';
            }
            blob = new Blob([s], { type: 'text/plain' });
            $download.get(0).href = window.URL.createObjectURL(blob);
            $download.get(0).download = 'rename.gitignore';
            $download.removeClass('disabled');
        }

        function ignore_obj(name) {
            return {
                name: name,
                selected: false,
                visible: true
            };
        }

        function ignore_selected(ig) {
            return ig.selected;
        }

        function ignore_selected_list(ignores) {
            return ignores.filter(ignore_selected).map(ig => ig.name);
        }

        function selected_to_text(ignores) {
            return ignore_selected_list(ignores).join(', ')
        }

        $(function () {
            window.vm = new Vue({
                el: '#vm',
                data: {
                    github_url: GITHUB_URL,
                    presets: PRESETS,
                    language_ignores: window.language_ignores.map(ignore_obj),
                    global_ignores: window.global_ignores.map(ignore_obj),
                    language_filter: '',
                    global_filter: '',
                    custom_ignore: CUSTOM_IGNORE
                },
                computed: {
                    language_selected: function () {
                        let s = selected_to_text(this.language_ignores);
                        return s === '' ? 'None' : s;
                    },
                    global_selected: function () {
                        let s = selected_to_text(this.global_ignores);
                        return s === '' ? 'None' : s;
                    }
                },
                watch: {
                    language_filter: function (newValue, oldValue) {
                        var s = newValue.toLowerCase();
                        this.language_ignores.forEach(ig => {
                            ig.visible = ig.name.toLowerCase().indexOf(s) >= 0;
                        });
                    },
                    global_filter: function (newValue, oldValue) {
                        var s = newValue.toLowerCase();
                        this.global_ignores.forEach(ig => {
                            ig.visible = ig.name.toLowerCase().indexOf(s) >= 0;
                        });
                    }
                },
                methods: {
                    use_preset: function (ps) {
                        console.log('use preset: ' + ps.name);
                        let
                            i,
                            ig;
                        for (i = 0; i < this.language_ignores.length; i++) {
                            ig = this.language_ignores[i];
                            ig.selected = ps.selection.indexOf(ig.name) >= 0;
                        }
                        for (i = 0; i < this.global_ignores.length; i++) {
                            ig = this.global_ignores[i];
                            ig.selected = ps.selection.indexOf(ig.name) >= 0;
                        }
                    },
                    generate: async function () {
                        let
                            list = [],
                            url_list = [],
                            igs;
                        igs = ignore_selected_list(this.language_ignores);
                        Array.prototype.push.apply(list, igs);
                        Array.prototype.push.apply(url_list, igs.map(ig => ig + '.gitignore'));

                        igs = ignore_selected_list(this.global_ignores);
                        Array.prototype.push.apply(list, igs);
                        Array.prototype.push.apply(url_list, igs.map(ig => 'Global/' + ig + '.gitignore'));

                        window.downloadVersion++;
                        await generate_gitignore(window.downloadVersion, list, url_list, this.custom_ignore);
                    }
                }
            });
        });
    </script>
</head>

<body>
    <div id="modal-generate" class="modal">
        <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">Generate Git Ignore</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body">
                    <h5 class="mb-4">Please wait for generation...</h5>
                    <div id="div-prompt">
                    </div>
                </div>
                <div class="modal-footer">
                    <a id="btn-download" href="#0" class="btn btn-primary">Download</a>
                </div>
            </div>
        </div>
    </div>
    <div class="container">
        <div class="row">
            <div class="col-12 mt-4 mb-2">
                <h3>Gitignore Online Generator</h3>
                <p>Fork me at <a target="_blank"
                        href="https://github.com/michaelliao/gitignore-online-generator">https://github.com/michaelliao/gitignore-online-generator
                        <i class="bi bi-box-arrow-up-right"></i></a>
                </p>
            </div>
        </div>
        <div class="row">
            <div class="col-12 mb-3">
                <div class="x-border" style="border-left: 0.25rem solid #5bc0de;">
                    <h5>Document</h5>
                    <p>This is an online tool for generating <code>.gitignore</code> file quickly by <a target="_blank"
                            href="https://github.com/michaelliao">Michael Liao
                            <i class="bi bi-box-arrow-up-right"></i></a>. The ignore files come from <a target="_blank"
                            href="https://github.com/github/gitignore">https://github.com/github/gitignore
                            <i class="bi bi-box-arrow-up-right"></i></a> with <a target="_blank"
                            href="https://github.com/michaelliao/gitignore-generator/blob/main/LICENSE">CC0
                            <i class="bi bi-box-arrow-up-right"></i></a> license.</p>
                    <p>Select language ignores and global ignores to generate your <code>.gitignore</code> file. Custom
                        ignore will be appended to the end.</p>
                    <p>Learn how <a target="_blank" href="https://git-scm.com/docs/gitignore">gitignore <i
                                class="bi bi-box-arrow-up-right"></i></a> works.</p>
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-12">
                <form id="vm" action="#0">
                    <div class="mb-3">
                        <label class="form-label">Use preset to quickly select ignores:</label>
                        <div class="btn-group">
                            <button v-for="ps in presets" v-text="ps.name" v-on:click="use_preset(ps)" type="button"
                                class="btn btn-outline-primary"></button>
                        </div>
                    </div>
                    <div class="mb-3">
                        <label class="form-label">Add language ignores:</label>
                        <div class="input-group mb-3">
                            <input v-model="language_filter" type="text" class="form-control" placeholder="Name filter">
                            <button v-on:click="language_filter=''" class="btn btn-outline-secondary" type="button">
                                <i class="bi bi-x-lg"></i></button>
                        </div>
                    </div>
                    <div class="mb-3 x-border x-select-container">
                        <div v-for="ig in language_ignores" v-show="ig.visible" class="form-check x-select">
                            <label class="form-check-label">
                                <input v-model="ig.selected" v-bind:value="ig.name" type="checkbox"
                                    class="form-check-input">
                                <span v-text="ig.name"></span>
                                <a target="_blank" title="View Source" v-bind:href="github_url+ig.name+'.gitignore'"><i
                                        class="bi bi-box-arrow-up-right"></i></a>
                            </label>
                        </div>
                    </div>
                    <div class="mb-3">
                        <label class="form-label">Add global ignores:</label>
                        <div class="input-group mb-3">
                            <input v-model="global_filter" type="text" class="form-control" placeholder="Name filter">
                            <button v-on:click="global_filter=''" class="btn btn-outline-secondary" type="button">
                                <i class="bi bi-x-lg"></i></button>
                        </div>
                    </div>
                    <div class="mb-3 x-border x-select-container">
                        <div v-for="ig in global_ignores" v-show="ig.visible" class="form-check x-select">
                            <label class="form-check-label">
                                <input v-model="ig.selected" v-bind:value="ig.name" type="checkbox"
                                    class="form-check-input">
                                <span v-text="ig.name"></span>
                                <a target="_blank" title="View Source"
                                    v-bind:href="github_url+'Global/'+ig.name+'.gitignore'"><i
                                        class="bi bi-box-arrow-up-right"></i></a>
                            </label>
                        </div>
                    </div>
                    <div class="mb-3">
                        <label for="customIgnore" class="form-label">Custom ignore:</label>
                        <textarea v-model="custom_ignore" class="form-control" id="customIgnore" rows="8"
                            style="resize: vertical; font-family: Monaco, 'Lucida Console', 'Courier New', Courier, monospace;">
# add your custom gitignore here:
!.gitignore
!.gitsubmodules
</textarea>
                    </div>
                    <div class="mb-3">
                        <div class="x-border" style="border-left: 0.25rem solid #5bc0de;">
                            <h5>Summary</h5>
                            <p>Language selected:</p>
                            <p style="text-indent: 2rem;" v-text="language_selected"></p>
                            <p>Global selected:</p>
                            <p style="text-indent: 2rem;" v-text="global_selected"></p>
                        </div>
                    </div>
                    <div class="mb-3">
                        <button v-on:click="generate"
                            v-bind:disabled="language_selected==='None' && global_selected==='None'" type="button"
                            class="btn btn-primary">Generate</button>
                    </div>
                </form>
            </div>
            <div class="col-12">
                <hr>
                <p>Copyleft 2022 @ <a target="_blank" href="https://github.com/michaelliao">michaelliao <i
                            class="bi bi-box-arrow-up-right"></i></a></p>
            </div>
        </div>
    </div>
</body>

</html>